package util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import orm.Result;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * Created by langdon on 2017/7/22.
 */
public class HTTPTool {
    public static String auth;
    public static String name;
    public static String url;
    public static String ip;
    public static String port;
    private static CloseableHttpClient httpClient;
    private static HttpContext context;

    public  HTTPTool(){
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(100);
        httpClient = HttpClients.custom()
                .setConnectionManager(cm)
                .build();
        context = new BasicHttpContext();
    }

    /**
     * 一切服务的开始，注册API，在网关中注册本服务
     * @return result
     */
    public static Result registerAPI(){
        Result result = new Result(502,"网关错误");
        try {
            CloseableHttpResponse response = httpClient.execute(
                    new HttpPost(url+":8000/application/api/v1/apis?ip="+ip+"&port="+port+"&name="+name), context);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                JSONObject content = JSON.parseObject(EntityUtils.toString(entity));
                result.setMsg((String) content.get("msg"));
                result.setStatus((int)content.get("status"));

                if(result.getStatus() == 200){
                    result.setMsg((String)content.get("auth"));
                    auth = (String)result.getMsg();//保存auth到本地
                }
            }
            response.close();
        } catch(IOException e){
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 一切服务的结束，撤销API,从网关中删除本服务
     */
    public static Result revokeAPI(){
        Result result = new Result(502,"网关错误");
        try {
            CloseableHttpResponse response = httpClient.execute(
                    new HttpDelete(url+":8000/application/api/v1/apis?name="+name+"&auth="+auth), context);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                JSONObject content = JSON.parseObject(EntityUtils.toString(entity));
                result = JSON.toJavaObject(content, Result.class);
            }
            response.close();
        }catch (IOException e){
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 请求转发
     * @param name 服务名称
     * @param requestUri 请求的URL
     * @param method HTTP方法
     * @return
     */
    public static Result requestApi(String name, String requestUri, int method){
        byte [] bytes= Base64.getUrlEncoder().encode(requestUri.getBytes(StandardCharsets.UTF_8));
        requestUri = new String(bytes, StandardCharsets.UTF_8);

        Result result = new Result(502,"网关错误");

        try {
            System.out.println(url+":8001/application/api/v1/dispatcher?name="+name+"&requestUri="+requestUri+"&method="+method);

            CloseableHttpResponse response = httpClient.execute(
                    new HttpGet(url+":8001/application/api/v1/dispatcher?name="+name+"&requestUri="+requestUri+"&method="+method), context);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                JSONObject content = JSON.parseObject(EntityUtils.toString(entity));
                result = JSON.toJavaObject(content, Result.class);
            }
            response.close();
        }catch (IOException e){
            e.printStackTrace();
        }
        return result;
    }
}
